package node_battle

import (
	"github.com/sniperHW/kendynet"
	"github.com/sniperHW/kendynet/event"
	"time"
	ss_rpc "sanguo/protocol/ss/rpc"
	"sync"
	"sanguo/rpc/createRoom"
	"github.com/golang/protobuf/proto"
	"strconv"
)

var (
	counter int
	wg sync.WaitGroup
	mutex sync.Mutex
)

const (
	Status1 = 1
	Status2
)

var (
	redisQueue *event.EventQueue
)

var (
	eventQueueList []*event.EventQueue
)

var queueIterator int32
var roomID int64
var queueCount int64
var roomTimer int64

type User struct {
	session kendynet.StreamSession
	status int32
	statusList []int32
	skills []*ss_rpc.Skill
	attributes []*ss_rpc.Attribute
	game string
	userId string
	roleId uint64
	weapon1 int32
	weapon2 int32
}

func (this *User) init(skills []*ss_rpc.Skill, attributes []*ss_rpc.Attribute,
	game string, userId string,
	roleId uint64, weapon1 int32, weapon2 int32) {
	this.statusList = []int32{}
	this.skills = skills
	this.attributes = attributes
	this.status = 0
	this.game = game
	this.userId = userId
	this.roleId = roleId
	this.weapon1 = weapon1
	this.weapon2 = weapon2
	this.skills = skills
	this.attributes = attributes
}

func (this *User) setStatus(s int32) {
	this.status = s
}

type Room struct {
	roomId	int64
	battleId int32
	users map[uint64]User
	queue *event.EventQueue
	nextTime int64
}

func (this *Room) init(roomId int64, battleId int32,
	roleinfos []*ss_rpc.RoleInfo,
	queue *event.EventQueue,
	nextTime int64) {
	this.roomId = roomId
	this.battleId = battleId
	this.queue = queue
	this.users = map[uint64]User{}
	this.nextTime = nextTime

	for  _, v := range roleinfos {
		var user User
		user.init(v.GetSkills(), v.GetBattleAttrs(), v.GetGame(),
			v.GetUserID(), v.GetRoleID(), v.GetWeapon1(), v.GetWeapon2())
		this.users[v.GetRoleID()] = user
	}
}

var (
	roomList []map[int64]Room
)

var (
	allUsers map[uint64]uint64
)

func queueCron(queue *event.EventQueue) {
	queue.Run()
}

func redisCron(queue *event.EventQueue) {
	queue.Run()
}

func timerCron() {
	for {
		time.Sleep(time.Duration(1)*time.Second)
		for k, v := range eventQueueList {
			v.Post(onCron, k)
		}
	}
}

func onCron(ret []interface{}) {
	index := ret[0].(int)
	t := time.Now()

	for k, v := range roomList[index] {
		if v.nextTime < t.Unix() {
			Debugln("delete roomid:%d %d %d\n", v.roomId, v.nextTime, t.Unix())
			if (k != v.roomId) {
				panic("room cron error")
			}
			delete(roomList[index], v.roomId)
		}
	}
}

func onCreateRoom(ret []interface{}) {
	Debugln("create room callback ---------->")
	index := ret[0].(int32)
	roomId := ret[1].(int64)
	room := ret[2].(Room)
	replyer := ret[3].(*createRoom.CreateRoomReplyer)

	_, ok := roomList[index][roomId]
	if (ok) {
		Debugln("create room failure1 ---------->", roomId)
		replyer.Reply(&ss_rpc.CreateRoomResp{Ok:proto.Int32(-1),
		})
		return
	}

	t := time.Now()
	roomList[index][roomId] = room
	Debugln("create roomid ---------->", roomId)

	token := strconv.FormatInt(t.Unix() + roomID,10)
	replyer.Reply(&ss_rpc.CreateRoomResp{Ok:proto.Int32(0),
		RoomID:proto.Int64(roomId), Token:proto.String(token), Time:proto.Int64(roomTimer),
	})
}

type CreateRoom struct {
	ok int32
	roomID int64
	token string
	time int64
}

func (this *CreateRoom) OnCall(replyer *createRoom.CreateRoomReplyer, arg *ss_rpc.CreateRoomReq) {
	t := time.Now()
	roomID = roomID + 1
	roomId := roomID + t.Unix()
	var room Room
	index := roomId % (queueCount - 1)

	Debugln("create room call ---------->", roomId)
	room.init(roomId, arg.GetBattlelevelID(), arg.GetRole(), eventQueueList[index],
		t.Unix() + roomTimer)

	if len(room.users) != len(arg.GetRole()) {
		Debugln("create room failure ---------->", roomId)
		replyer.Reply(&ss_rpc.CreateRoomResp{Ok:proto.Int32(-1),
		})
		return
	}
	eventQueueList[index].Post(onCreateRoom, int32(index), roomId, room, replyer)
}

func xxStatus(user *User) {

}
